<?php

/**
 * Green Calc
 * Calc entry point file for Calc Component (reserved. using plugin Calc)
 * 2009-2014 All rights reserved
 * @link http://www.greenkey.ru
 * @license GNU/GPL v3
 */
// No direct access
defined('_JEXEC') or die;

jimport('joomla.application.component.model');

/**
 * Calc Model
 * 
 *  it can be JModel, or JModelItem
 *
 */
class CalcModelCalc extends JModelItem {

    protected $selfie;
    
    protected $calc;
    
    protected $calc_vars;

    /**
     * Gets Selfie (test function)
     * 
     * @return string Selfie
     */
    function getSelfie() {
        if (!isset($this->selfie)) {

            // This is input from address line
            $jinput = JFactory::getApplication()->input;
            // id atribute setted in view/tmpl/xml file!!!
            $x = $jinput->get('selfie', 1, 'INT');

            // Также можно получить состояние
            // $x = (int) $this->getState('message.selfie');

            switch ($x) {
                case 2:
                    $this->selfie = 'Caption selfie is 2';
                    break;
                default:
                case 1:
                    $this->selfie = 'Caption selfie is 1';
                    break;
            }
        }
        return $this->selfie;
    }

    /**
     * Returns a reference to the a Table object, always creating it.
     *
     * @param       type    The table type to instantiate
     * @param       string  A prefix for the table class name. Optional.
     * @param       array   Configuration array for model. Optional.
     * 
     * @return      JTable  A database object
     * @since       2.5
     */
    public function getTable($type = 'Calc', $prefix = 'CalcTable', $config = array()) {
        return JTable::getInstance($type, $prefix, $config);
    }

    /**
     * 
     * Получение записи расчета.
     * Внимание! В данном варианте используется JTable,
     * и получение данных основано на нем. Годится, когда надо получить данные из 
     * 1 таблицы. Если надо получать из двух, то надо передалывать процедуры
     * на GetItem
     * 
     * @param type $id
     * 
     * @return type
     */
    public function getCalc($id = 1) {
        if (!is_array($this->calc)) {
            $this->calc = array();
        }

        if (!isset($this->calc[$id])) {
            //request the selected id
            $jinput = JFactory::getApplication()->input;
            $id = $jinput->get('id', 1, 'INT');

            // Get a TableCalc instance
            $table = $this->getTable();

            // Load the caption
            if (!$table->load($id)) {
                throw new Exception(COM_CALC_ERROR_ITEM_NOT_FOUND);
            }


            // Assign the message
            $this->calc[$id]->caption = $table->caption;
            $this->calc[$id]->description = $table->description;

            //Get Params
            $params = new JRegistry;
            $params->loadString($table->params);
            $this->calc[$id]->params = $params;
        }

        return $this->calc[$id];
    }

    /**
     * Получаем сообщение.
     *
     * @param   int  $id  Id сообщения.
     *
     * @return  object  Объект сообщения, которое отображается пользователю.
     *
     * @throws  Exception  Если сообщение не найдено.
     *
     */
    public function getItem($id = null) {
        // Если id не установлено, то получаем его из состояния.
        $id = (!empty($id)) ? $id : (int) $this->getState('calc.id');

        if ($this->_item === null) {
            $this->_item = array();
        }

        if (!isset($this->_item[$id])) {
            // Конструируем SQL запрос.
            $query = $this->_db->getQuery(true);
            $query->select('caption, description, formula, variables, params')
                    ->from('#__calc')
                    ->where('id = ' . (int) $id)
                    ->where('state > 0');

            $this->_db->setQuery($query);
            $data = $this->_db->loadObject();

            // Генерируем исключение, если сообщение не найдено.
            if (empty($data)) {
                throw new Exception(JText::_('COM_CALC_ERROR_MESSAGE_NOT_FOUND'), 404);
            }

            // Загружаем JSON строку параметров.
            $params = new JRegistry;
            $params->loadString($data->params);
            $data->params = $params;

            // Объединяем глобальные параметры с индивидуальными.
            $params = clone $this->getState('params');
            $params->merge($data->params);
            $data->params = $params;

            $this->_item[$id] = $data;
        }

        return $this->_item[$id];
    }

    /**
     * 
     * Загрузка Calc_vars таблицы с предопределенными переменными
     * 
     * @param type $id
     * @return type
     */
    public function getCalcVars($id = null) {
        // Можно загружать по одному, либо сразу все.
        // Будем загружать сразу все - так меньше запросов к базе
        // Но больше нагрузка на браузер

        if ($this->calc_vars === null) {
            $query = $this->_db->getQuery(true);
            $query->select('name, vvalues')
                    ->from('#__calc_vars');

            $this->_db->setQuery($query);
            $this->calc_vars = $this->_db->loadObjectList("name");
        }
        
        return $this->calc_vars;
    }

    /**
     * Метод для авто-заполнения состояния модели.
     * Заметка. Вызов метода getState в этом методе приведет к рекурсии.
     * 
     * @return  void
     */
    protected function populateState() {
        $app = JFactory::getApplication();
        // Получаем Selfie сообщения из Запроса.
        $x = $app->input->getInt('selfie', 0);
        // Получаем id из запроса
        $id = $app->input->getInt('id', 0);

        // Добавляем сообщения в состояние модели.
        $this->setState('calc.selfie', $x);
        $this->setState('calc.id', $id);

        // Загружаем глобальные параметры.
        $params = $app->getParams();

        // Добавляем параметры в состояние модели.
        $this->setState('params', $params);

        parent::populateState();
    }

}
